feat: header 알림 패널 목업 페이지 추가 - #21
Conversation
알림 아이콘에 패널·mock을 연동하고, 견적 요청 완료 후 이동 경로를 /estimates/pending으로 맞춘다. Co-authored-by: Cursor <cursoragent@cursor.com>
미읽음 수 배지를 표시하고, 타입별 고정 문구에 content를 삽입해 강조하며 읽은 알림은 연한 회색으로 구분한다. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthrough헤더에 목데이터 기반 알림 패널, 읽지 않은 알림 배지, 페이지네이션 및 닫기 동작을 추가했습니다. 견적 CTA 경로와 리뷰 접근성·표시 이름 fallback도 변경했습니다. Changes헤더 알림 패널
견적·리뷰·인증 보완
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
actor 사용자
participant Header
participant NotificationPanel
사용자->>Header: 알림 토글 클릭
Header->>NotificationPanel: 패널 표시 및 onClose 전달
사용자->>NotificationPanel: 닫기 또는 알림 링크 클릭
NotificationPanel->>Header: onClose 호출
Header->>NotificationPanel: 패널 닫기
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
src/components/common/Header/notificationMessages.ts (1)
68-71: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value객체 타입은
interface로 선언하세요.
NotificationMessagePart는 확장 가능한 객체 구조이므로 프로젝트 규칙에 맞게interface NotificationMessagePart로 바꾸는 편이 일관적입니다.수정 예시
-export type NotificationMessagePart = { +export interface NotificationMessagePart { text: string; highlight?: boolean; -}; +}As per coding guidelines, 객체 형태 타입은
interface를 우선 사용해야 합니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/common/Header/notificationMessages.ts` around lines 68 - 71, Change NotificationMessagePart from an object type alias to an interface while preserving its text property and optional highlight property.Source: Coding guidelines
src/components/common/Header/NotificationPanel.tsx (1)
46-46: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win패널 그림자는 디자인 토큰으로 교체하세요.
shadow-[2px_2px_8px_0_rgba(0,0,0,0.06)]는 알림 패널의 shadow를 하드코딩합니다. 기존 semantic shadow utility를 사용하거나, 없다면 토큰에 추가한 뒤 사용하세요.As per path instructions, 알림 패널의 shadow는 하드코딩하지 않고 디자인 토큰 기반으로 사용해야 합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/common/Header/NotificationPanel.tsx` at line 46, Replace the hardcoded shadow utility in the NotificationPanel class string with the existing semantic shadow utility for panels. If no suitable utility exists, add the corresponding design token first, then reference that token instead of using an arbitrary shadow value; keep the remaining styling unchanged.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/app/layout.tsx`:
- Around line 36-37: Update the root layout’s Header usage so isLogin is derived
from the actual authentication state rather than being hardcoded true. Remove
the temporary notification-panel fixture comment/state from the global layout,
and isolate it in a development-only fixture or Storybook while preserving
unauthenticated and login-page headers.
In `@src/components/common/Header/NotificationPanel.tsx`:
- Around line 79-107: Update the notification item rendering in
NotificationPanel so notifications with a linkUrl wrap their content in
next/link’s Link and navigate to that URL. Keep notifications without linkUrl
non-clickable and preserve the existing styling and message/timestamp content.
---
Nitpick comments:
In `@src/components/common/Header/notificationMessages.ts`:
- Around line 68-71: Change NotificationMessagePart from an object type alias to
an interface while preserving its text property and optional highlight property.
In `@src/components/common/Header/NotificationPanel.tsx`:
- Line 46: Replace the hardcoded shadow utility in the NotificationPanel class
string with the existing semantic shadow utility for panels. If no suitable
utility exists, add the corresponding design token first, then reference that
token instead of using an arbitrary shadow value; keep the remaining styling
unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 316c2032-ebe7-4321-92e1-60714d7be331
📒 Files selected for processing (7)
src/app/layout.tsxsrc/components/common/Header/Header.tsxsrc/components/common/Header/NotificationPanel.tsxsrc/components/common/Header/notificationMessages.tssrc/components/estimate/EstimateRequestForm.tsxsrc/lib/mocks/notifications.mock.tssrc/types/notification.ts
juengseulki
left a comment
There was a problem hiding this comment.
📋 PR 리뷰
👍 좋았던 점
- 알림 타입과 메시지 조합 로직을 별도 파일로 분리해 NotificationPanel이 UI 렌더링에 집중하도록 구성한 점이 좋았습니다.
- 알림 패널의 바깥 클릭과 Escape 닫기를 모두 지원해 기본적인 사용성을 잘 챙겼습니다.
- 알림 버튼에 aria-expanded, aria-controls, 읽지 않은 알림 수가 포함된 aria-label을 적용한 점도 좋았습니다.
- 읽음 여부에 따라 메시지와 시간의 색상을 함께 변경해 상태가 명확하게 구분됩니다.
- 페이지네이션 버튼의 disabled 상태와 aria-current를 적용해 현재 페이지를 구분한 점도 좋았습니다.
- 견적 요청 완료 후 이동 경로를 /estimates/pending으로 수정한 것도 현재 라우팅 구조에 맞습니다.
🚨 수정이 필요한 부분
- 루트 레이아웃에서 isLogin을 고정하면 모든 페이지가 로그인 Header로 표시됩니다.
- linkUrl이 있는 알림도 현재 이동 기능이 없어 관련 화면에 접근할 수 없습니다.
🔍 확인 및 제안
인라인 코멘트로 아래 내용을 남기면 좋을 것 같습니다.
- 알림이 없는 경우 빈 상태 UI를 제공할 계획인지 궁금합니다.
- 알림 content가 가변 강조 문구인지 완성된 메시지인지 백엔드 API와 합의된 구조인지 확인이 필요합니다.
전체적으로 알림 패널의 UI 구성과 접근성 처리는 꼼꼼하게 되어 있습니다. 다만 전역 로그인 상태 고정과 알림 이동 기능은 실제 서비스 동작에 영향을 주기 때문에 수정 후 머지하는 것이 좋겠습니다. 😊
알림 아이콘에 패널·mock을 연동하고, 견적 요청 완료 후 이동 경로를 /estimates/pending으로 맞춘다. Co-authored-by: Cursor <cursoragent@cursor.com>
미읽음 수 배지를 표시하고, 타입별 고정 문구에 content를 삽입해 강조하며 읽은 알림은 연한 회색으로 구분한다. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
src/components/common/Header/Header.tsx (2)
168-186: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win알림 배지에
Text컴포넌트 미사용 +aria-controls패턴 불일치.
- 배지
<span>이text-[length:var(--font-size-12)]같은 임의 텍스트 크기 클래스를 직접 사용합니다. 프로필 메뉴 등 다른 텍스트는 모두Textvariant를 쓰는데 이 배지만 예외입니다.aria-controls={notificationPanelId}는 패널이 닫혀 DOM에 없을 때도 항상 설정되는 반면, 바로 아래 프로필 트리거(Line 204)는isProfileMenuOpen ? ... : undefined로 조건부 처리합니다. 같은 파일 안에서 패턴이 갈립니다.As per path instructions, "텍스트는 Text 컴포넌트의 variant 를 사용합니다... 직접 text-[16px] 같은 클래스를 쓰면 지적해 주세요."
🎨 Text 컴포넌트 및 aria-controls 일관화
- aria-controls={notificationPanelId} + aria-controls={isNotificationOpen ? notificationPanelId : undefined}{unreadCount > 0 ? ( - <span + <Text + as="span" aria-hidden="true" - className="bg-status-error text-text-inverse absolute -top-4 -right-6 flex h-16 min-w-16 items-center justify-center rounded-full px-4 text-[length:var(--font-size-12)] leading-none font-semibold" + variant="sm-semibold" // 프로젝트에 정의된 배지/캡션용 variant로 교체 + className="bg-status-error text-text-inverse absolute -top-4 -right-6 flex h-16 min-w-16 items-center justify-center rounded-full px-4 leading-none" > {unreadCount} - </span> + </Text> ) : null}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/common/Header/Header.tsx` around lines 168 - 186, Update the notification badge in the header to use the existing Text component with the appropriate variant instead of the direct text-[length:var(--font-size-12)] class, preserving its current visual styling. Make aria-controls conditional like the profile trigger: provide notificationPanelId only when isNotificationOpen is true, otherwise pass undefined.Source: Path instructions
52-69: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win알림 패널 닫힐 때 포커스 복원 누락.
closeNotification이 상태만 끄고 트리거 버튼으로 포커스를 되돌리지 않습니다. 반면 아래 프로필 메뉴의closeMenu(Line 71-74)는triggerRef.current?.focus()로 복원합니다. 사용자가 패널 안(페이지네이션 버튼 등)으로 Tab 이동 후 Escape를 누르면 포커스가 사라진 DOM을 따라가 유실됩니다.As per coding guidelines, "키보드 접근성, focus·disabled·hover·active 상태, aria 속성, 모달 focus 관리... 확인한다".
♿ 프로필 메뉴 패턴과 일관되게 포커스 복원
+ const notificationTriggerRef = useRef<HTMLButtonElement>(null); + const closeNotification = useCallback(() => { setIsNotificationOpen(false); + notificationTriggerRef.current?.focus(); }, []);그리고 버튼에 ref 연결:
<button + ref={notificationTriggerRef} type="button" aria-label={unreadCount > 0 ? `알림, 읽지 않은 알림 ${unreadCount}개` : "알림"}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/common/Header/Header.tsx` around lines 52 - 69, Update closeNotification in Header to restore focus to the notification trigger via its ref after closing, matching the profile menu’s closeMenu behavior. Ensure the trigger button is connected to the corresponding ref so Escape or outside-click closure returns focus correctly.Source: Coding guidelines
svgr.options.ts (1)
35-43: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win다색 아이콘 규칙에도
svgoConfig를 넣어convertColors를 끄세요.svgrColorOptions는 현재 SVGO 기본값을 그대로 타서 색 값이 정규화될 수 있습니다.**/icons/color/*.svg는 원색 유지가 목적이니preset-default에서convertColors: false를 명시하는 게 안전합니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@svgr.options.ts` around lines 35 - 43, Update the svgrColorOptions configuration to include an svgoConfig using the preset-default plugin with convertColors disabled, preserving original colors for icons under the color path while leaving the existing runtimeConfig, icon, and svgProps settings unchanged.
🧹 Nitpick comments (3)
src/components/review/ReviewStarRating.tsx (1)
62-82: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift
radiogroup패턴의 키보드 상호작용이 빠져 있습니다.WAI-ARIA radio group은 그룹이 하나의 탭 정지점을 갖고 화살표 키로 선택을 이동합니다. 현재는 별 5개가 모두 탭 정지점이며 화살표 키 처리가 없어 스크린 리더 사용자가 예상과 다르게 동작합니다. roving tabindex +
onKeyDown을 추가하거나, 더 간단하게는 sr-only<input type="radio">+<label>조합으로 브라우저 기본 동작에 위임하는 방법을 권합니다.♿ roving tabindex 최소 적용 예
<button key={starValue} type="button" role="radio" aria-checked={starValue === clamped} aria-label={`${label} ${starValue}점`} + tabIndex={starValue === (clamped || 1) ? 0 : -1} disabled={disabled}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/review/ReviewStarRating.tsx` around lines 62 - 82, Update the radio-group implementation around the star button mapping so only the currently selected star is tabbable via roving tabindex, while unselected stars use tabindex -1. Add keyboard handling for ArrowLeft/ArrowUp and ArrowRight/ArrowDown to move selection appropriately and call onChange, while preserving disabled behavior and the existing aria-checked state.Source: Coding guidelines
src/components/review/ReviewsShell.tsx (1)
1-19: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
"use client"는 제거해도 됩니다.
이 컴포넌트는 상태나 훅이 없고,ReviewTabs만 클라이언트 컴포넌트로 두면 됩니다. 셸은 서버 컴포넌트로 유지해서 클라이언트 경계를 더 좁히세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/review/ReviewsShell.tsx` around lines 1 - 19, Remove the "use client" directive from ReviewsShell so it remains a server component, while keeping ReviewTabs as the client component that provides the interactive behavior. Preserve the existing ReviewsShellProps interface and children rendering unchanged.Source: Coding guidelines
src/components/common/Header/Header.tsx (1)
58-69: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winEscape 처리를 공용 훅으로 분리해도 좋습니다.
알림 패널과 프로필 메뉴가 각각 Escape 리스너를 직접 등록합니다.useEscapeKey(isOpen, onEscape)같은 훅으로 묶고, 프로필 메뉴의 화살표/Home/End 처리만 남기면 중복이 줄어듭니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/common/Header/Header.tsx` around lines 58 - 69, Extract the Escape-key listener logic from Header’s notification effect into a shared useEscapeKey(isOpen, onEscape) hook, then use that hook for the notification panel and profile menu. Remove their duplicated Escape listener setup while preserving the profile menu’s existing Arrow/Home/End keyboard handling.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/review/MyReviewCard.tsx`:
- Around line 29-30: Remove the redundant aria-label from the element using
aria-labelledby in MyReviewCard, leaving aria-labelledby as the single
accessible-name source so the existing heading-based link name remains
authoritative.
In `@src/components/review/ReviewTabs.tsx`:
- Around line 20-23: Review the nav element in ReviewTabs and replace the
hardcoded shadow-[0_2px_5px_0_rgba(...)] utility with the appropriate semantic
shadow-* utility defined by the project’s design tokens in tokens.theme.css,
preserving the existing border and layout classes.
In `@src/components/review/WritableReviewCard.tsx`:
- Line 21: Update the displayName fallback in
src/components/review/WritableReviewCard.tsx:21-21 and
src/components/review/ReviewWriteModal.tsx:51-51 from the literal "기사님" to
mover.name, preserving the existing trimmed nickname behavior. This keeps the
rendered title and aria-label references in WritableReviewCard and
ReviewWriteModal from duplicating the suffix.
In `@src/lib/auth/session.ts`:
- Around line 23-55: 분리된 브라우저 이벤트 계층으로 notifyAuthSessionChange와
subscribeAuthSession의 window.dispatchEvent 및 전역 리스너 등록·해제 로직을 이동하고,
src/lib/auth/session.ts에는 순수한 인증 세션 로직만 남기세요. 인증 모듈에서 해당 부수효과를 유지해야 한다면 이 파일을
규칙의 명시적 예외로 문서화하세요.
In `@src/lib/mocks/reviews.mock.ts`:
- Around line 231-245: Update getMockMyReviews to normalize query.limit to a
positive integer before calculating totalPages, pagination, and slicing; ensure
zero, negative, and non-integer limits cannot produce Infinity or broken
pagination, while preserving the existing default behavior for omitted limits.
---
Outside diff comments:
In `@src/components/common/Header/Header.tsx`:
- Around line 168-186: Update the notification badge in the header to use the
existing Text component with the appropriate variant instead of the direct
text-[length:var(--font-size-12)] class, preserving its current visual styling.
Make aria-controls conditional like the profile trigger: provide
notificationPanelId only when isNotificationOpen is true, otherwise pass
undefined.
- Around line 52-69: Update closeNotification in Header to restore focus to the
notification trigger via its ref after closing, matching the profile menu’s
closeMenu behavior. Ensure the trigger button is connected to the corresponding
ref so Escape or outside-click closure returns focus correctly.
In `@svgr.options.ts`:
- Around line 35-43: Update the svgrColorOptions configuration to include an
svgoConfig using the preset-default plugin with convertColors disabled,
preserving original colors for icons under the color path while leaving the
existing runtimeConfig, icon, and svgProps settings unchanged.
---
Nitpick comments:
In `@src/components/common/Header/Header.tsx`:
- Around line 58-69: Extract the Escape-key listener logic from Header’s
notification effect into a shared useEscapeKey(isOpen, onEscape) hook, then use
that hook for the notification panel and profile menu. Remove their duplicated
Escape listener setup while preserving the profile menu’s existing
Arrow/Home/End keyboard handling.
In `@src/components/review/ReviewsShell.tsx`:
- Around line 1-19: Remove the "use client" directive from ReviewsShell so it
remains a server component, while keeping ReviewTabs as the client component
that provides the interactive behavior. Preserve the existing ReviewsShellProps
interface and children rendering unchanged.
In `@src/components/review/ReviewStarRating.tsx`:
- Around line 62-82: Update the radio-group implementation around the star
button mapping so only the currently selected star is tabbable via roving
tabindex, while unselected stars use tabindex -1. Add keyboard handling for
ArrowLeft/ArrowUp and ArrowRight/ArrowDown to move selection appropriately and
call onChange, while preserving disabled behavior and the existing aria-checked
state.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: e1bc0fce-f82c-44c9-9371-aeff0035088c
📒 Files selected for processing (31)
next.config.tssrc/app/reviews/layout.tsxsrc/app/reviews/me/page.tsxsrc/app/reviews/page.tsxsrc/app/reviews/writable/page.tsxsrc/components/common/Header/Header.tsxsrc/components/estimate/EstimateRequestForm.tsxsrc/components/estimate/pending/PendingEstimateCard.tsxsrc/components/review/MyReviewCard.tsxsrc/components/review/MyReviewsPageClient.tsxsrc/components/review/ReviewEmptyState.tsxsrc/components/review/ReviewPageFrame.tsxsrc/components/review/ReviewStarRating.tsxsrc/components/review/ReviewTabs.tsxsrc/components/review/ReviewWriteModal.tsxsrc/components/review/ReviewsShell.tsxsrc/components/review/WritableReviewCard.tsxsrc/components/review/WritableReviewsPageClient.tsxsrc/hooks/useCreateReview.tssrc/hooks/useMyReviews.tssrc/hooks/useReviewableEstimates.tssrc/lib/api/reviews.tssrc/lib/auth/session.tssrc/lib/constants/apiRoutes.tssrc/lib/constants/appRoutes.tssrc/lib/constants/queryKeys.tssrc/lib/dev-auth.tssrc/lib/mocks/reviews.mock.tssrc/types/estimate.tssrc/types/review.tssvgr.options.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/components/estimate/EstimateRequestForm.tsx
7ba4d53 to
7c529ec
Compare
|
작업 고생 많으셨습니다! 👍 크게 문제는 없어보이는데, Text component 이용과 shadow token 에 대해 인라인 코멘트 남겨두겠습니다! |
알림 linkUrl이 있는 항목은 클릭 이동 시 패널이 닫히도록 하고, 알림이 없을 때는 빈 상태 문구를 표시하며 페이지네이션을 숨긴다. Co-authored-by: Cursor <cursoragent@cursor.com>
feature/estimate-request 브랜치에 최신 dev 변경사항을 병합하고 Header 충돌을 해소한다. Co-authored-by: Cursor <cursoragent@cursor.com>
Header 병합 충돌을 해결해 feature/estimate-request와 원격 브랜치 상태를 동기화한다. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/common/Header/Header.tsx`:
- Around line 174-194: Update the notification button in Header so aria-controls
references notificationPanelId only when isNotificationOpen is true; omit the
attribute while the conditionally rendered NotificationPanel is closed, matching
the profile menu’s conditional ARIA behavior.
In `@src/components/estimate/EstimateRequestForm.tsx`:
- Line 321: Update the CTA text associated with the /estimates/pending link in
EstimateRequestForm so it refers to pending or in-progress estimates rather than
received estimates, matching the destination’s established naming.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: ad3d0f77-f67a-4f85-9eb3-3534b447a655
📒 Files selected for processing (6)
src/components/common/Header/Header.tsxsrc/components/common/Header/NotificationPanel.tsxsrc/components/common/Header/notificationMessages.tssrc/components/estimate/EstimateRequestForm.tsxsrc/lib/mocks/notifications.mock.tssrc/types/notification.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- src/types/notification.ts
- src/lib/mocks/notifications.mock.ts
- src/components/common/Header/notificationMessages.ts
- src/components/common/Header/NotificationPanel.tsx
리뷰 카드와 작성 모달의 표시명 fallback을 mover.name으로 통일하고, 알림 버튼 aria-controls 조건부 처리 및 인증 세션 이벤트 예외 문서를 보강한다. Co-authored-by: Cursor <cursoragent@cursor.com>
배지 숫자에 Text 컴포넌트를 적용하고, 알림 패널 그림자를 디자인 토큰(shadow-notification)으로 치환해 스타일 일관성을 맞춘다. Co-authored-by: Cursor <cursoragent@cursor.com>
styles 토큰 충돌을 해결하고 notification/toast shadow 토큰을 모두 반영한다. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/common/Header/Header.tsx (1)
47-68: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win알림 패널을 닫을 때 트리거 버튼으로 포커스를 복귀시켜 주세요.
현재
closeNotification은 패널만 제거하므로 닫기 버튼이나Escape로 닫은 뒤 포커스가 제거될 요소에 남습니다. 알림 버튼에 ref를 연결하고 키보드 닫기 경로에서는 해당 버튼으로 포커스를 복귀하세요. 바깥 클릭 닫기에서는 사용자의 클릭 위치를 빼앗지 않도록 별도 경로로 처리하는 것이 좋습니다.Also applies to: 174-198
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/common/Header/Header.tsx` around lines 47 - 68, Update closeNotification and the notification trigger flow to restore focus to the notification button when the panel closes via its close button or Escape. Add and attach a ref to the trigger button, and use a keyboard/programmatic close path that focuses it after closing; keep outside-click dismissal separate so it does not steal focus from the user’s click target.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@src/components/common/Header/Header.tsx`:
- Around line 47-68: Update closeNotification and the notification trigger flow
to restore focus to the notification button when the panel closes via its close
button or Escape. Add and attach a ref to the trigger button, and use a
keyboard/programmatic close path that focuses it after closing; keep
outside-click dismissal separate so it does not steal focus from the user’s
click target.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 57faab64-c1aa-4c5f-8053-b051423e6d39
📒 Files selected for processing (3)
src/components/common/Header/Header.tsxsrc/components/common/Header/NotificationPanel.tsxsrc/styles/tokens.theme.css
📋 작업 내용
헤더 알림 아이콘에 알림 패널 추가(목업데이터 조회 및 페이지네이션), 안읽은 알림 갯수 라벨 및 읽은 알림은 디자인 변경
🔥 변경 사항
type,content,isRead등)에 맞춘 공통 타입을 추가했습니다.prefix/suffix)를 정의하고, 가변content를 주황 강조 구간으로 넣는buildNotificationMessageParts함수를 추가했습니다.isLoginprop 추가했습니다.+) src/components/estimate/EstimateRequestForm.tsx: 견적 요청 완료 후 이동 경로를
/estimates에서/estimates/pending으로 수정했습니다.✅ 체크리스트
📷 스크린샷 (선택)
🔗 관련 이슈
Closes #
💬 To Reviewer
Summary by CodeRabbit